package com.godGuang.payment.service;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.godGuang.payment.config.AlipayConfigProperties;
import com.godGuang.payment.config.model.TradePayModel;
import com.godGuang.payment.config.model.TradeQueryModel;
import com.godGuang.payment.config.model.TradeRefundModel;
import com.godGuang.payment.config.model.TradeRefundQueryModel;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


@Component
@Log4j2
public class AliPayService {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    private AlipayConfigProperties alipayConfigProperties;
    @Autowired
    private AlipayClient alipayClient;


    //public void tradePay(String orderNumber) {
    //    Order order = orderTemplate.findByOrder(orderNumber);
    //    if (null==order){throw new RuntimeException("订单不存在");}
    //    this.Pay(order.getOrderAmount());
    //}


    /**
     * 发起支付
     */
    public String Pay(Integer money) {
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(alipayConfigProperties.getReturnUrl());
        alipayRequest.setNotifyUrl(alipayConfigProperties.getNotifyUrl());
        alipayRequest.setBizContent(TradePayModel.builder()
                .outTradeNo(UUID.randomUUID().toString().replaceAll("-",""))
                .totalAmount(money)
                .subject("随便充点")
                .body("哇 来单了")
                .productCode("FAST_INSTANT_TRADE_PAY")
                .build()
                .toJsonStr());
        try {
            AlipayTradePagePayResponse alipayTradeRefundResponse = alipayClient.pageExecute(alipayRequest);
            log.info("请求成功:{}", alipayTradeRefundResponse);
            log.info("请求成功:{}", alipayTradeRefundResponse.getBody());
            response.setContentType("text/html;charset=UTF-8");
            //response.getWriter().println(alipayTradeRefundResponse.getBody());
            return alipayTradeRefundResponse.getBody();
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }


    public void Pay2(Integer money) {
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(alipayConfigProperties.getReturnUrl());
        alipayRequest.setNotifyUrl(alipayConfigProperties.getNotifyUrl());
        alipayRequest.setBizContent(TradePayModel.builder()
                .outTradeNo(UUID.randomUUID().toString().replaceAll("-",""))
                .totalAmount(money)
                .subject("随便打车收费")
                .body("随意打车")
                .productCode("FAST_INSTANT_TRADE_PAY")
                .build()
                .toJsonStr());
        try {
            AlipayTradePagePayResponse alipayTradeRefundResponse = alipayClient.pageExecute(alipayRequest);
            log.info("请求成功:{}", alipayTradeRefundResponse);
            log.info("请求成功:{}", alipayTradeRefundResponse.getBody());
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().println(alipayTradeRefundResponse.getBody());
            //return alipayTradeRefundResponse.getBody();
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 交易查询
     */
    public String tradeQuery(String orderNumber) {
        //设置请求参数
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
        alipayRequest.setBizContent(
                TradeQueryModel.builder()
                        .outTradeNo(orderNumber)
                        .tradeNo("")
                        .build()
                        .toJsonStr()
        );
        try {
            AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.execute(alipayRequest);
            log.info("请求成功:{}", alipayTradeQueryResponse);
            log.info("请求成功:{}", alipayTradeQueryResponse.getBody());
            return alipayTradeQueryResponse.getBody();
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 交易关闭
     */
    public void tradeClose() {
        //设置请求参数
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();

        alipayRequest.setBizContent(
                TradeQueryModel.builder()
                        .outTradeNo("1212111")
                        .tradeNo("")
                        .build()
                        .toJsonStr()
        );
        try {
            AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.execute(alipayRequest);
            log.info("请求成功:{}", alipayTradeQueryResponse);
            log.info("请求成功:{}", alipayTradeQueryResponse.getBody());
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 退单
     */
    public void tradeRefund() {
        //设置请求参数
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();

        alipayRequest.setBizContent(
                TradeRefundModel.builder()
                        .outTradeNo("1212111")
                        .tradeNo("")
                        .refundAmount("")
                        .refundReason("")
                        .outRequestNo("")
                        .build().toJsonStr());

        try {
            AlipayTradeRefundResponse alipayTradeRefundResponse = alipayClient.execute(alipayRequest);
            log.info("请求成功:{}", alipayTradeRefundResponse);
            log.info("请求成功:{}", alipayTradeRefundResponse.getBody());
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 退款查询
     */
    public void tradeRefundQuery() {
        //设置请求参数
        AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();

        alipayRequest.setBizContent(
                TradeRefundQueryModel.builder()
                        .outTradeNo("1212111")
                        .tradeNo("")
                        .outRequestNo("")
                        .build()
                        .toJsonStr());
        try {
            AlipayTradeFastpayRefundQueryResponse alipayTradeFastpayRefundQueryResponse = alipayClient.execute(alipayRequest);
            log.info("请求成功:{}", alipayTradeFastpayRefundQueryResponse);
            log.info("请求成功:{}", alipayTradeFastpayRefundQueryResponse.getBody());
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 交易返回
     */
    public void tradeReturn() {
        Map<String, String> params = new HashMap<>();
        request.getParameterMap().forEach((key, value) -> params.put(key, ArrayUtils.toString(value)));
        if (signVerified(params)) {
            //商户订单号
            String out_trade_no = params.get("out_trade_no");

            //支付宝交易号
            String trade_no = params.get("trade_no");

            //付款金额
            String total_amount = params.get("total_amount");

            System.out.println("trade_no:" + trade_no);
            System.out.println("out_trade_no:" + out_trade_no);
            System.out.println("total_amount:" + total_amount);
        } else {
            System.out.println("验签失败");
        }
    }

    /**
     * 回调地址
     */
    public void tradeNotifyUrl() {
        Map<String, String> params = new HashMap<>();
        request.getParameterMap().forEach((key, value) -> params.put(key, ArrayUtils.toString(value)));
        if (signVerified(params)) {//验证成功
            //商户订单号
            String out_trade_no = params.get("KIoXBJgz0bYE");

            //支付宝交易号
            String trade_no = params.get("trade_no");
            //交易状态
            String trade_status = params.get("trade_status");
            if (trade_status.equals("TRADE_FINISHED")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序
                System.out.println(trade_status + "交易完成不可退款");
                //注意：
                //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知.0
            } else if (trade_status.equals("TRADE_SUCCESS")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序
                System.out.println(trade_status + "交易完成");
                //注意：
                //付款完成后，支付宝系统发送该交易状态通知
            }

            System.out.println("success");

        } else {//验证失败
            System.out.println("fail");

            //调试用，写文本函数记录程序运行情况是否正常
            //String sWord = AlipaySignature.getSignCheckContentV1(params);
            //AlipayConfig.logResult(sWord);
        }
    }


    private boolean signVerified(Map<String, String> params) {

//        requestParams.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, (Function<Map.Entry<String, String[]>, Object>) stringEntry -> ArrayUtils.toString(stringEntry.getValue())));
        try {
            return AlipaySignature.rsaCheckV1(params,
                    alipayConfigProperties.getAlipayPublicKey(),
                    alipayConfigProperties.getCharset(),
                    alipayConfigProperties.getSignType());
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }


}
